﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CloudStorageLight.Core;

namespace CloudStorageLight.Core.Tests
{
    [TestClass]
    public class CompositeBlobContainerTest
    {

        private CompositeBlobContainer _Container;

        public CompositeBlobContainer Container
        {
            get 
            { 
                if (_Container == null)
                {
                    var list = new List<BlobAdapterBase>();

                    var spsUrl = AppUtil.GetAppConfigValue("sps.url");
                    var user = AppUtil.GetAppConfigValue("sps.user");
                    var pass = AppUtil.GetAppConfigValue("sps.pass");
                    list.Add(new SpsBlobAdapter("/SPS/", spsUrl, user, pass, "Shared Documents"));

                    var workFolder = "CompUnit";
                    if (Directory.Exists(workFolder)) Directory.Delete(workFolder, true);
                    var direInfo = Directory.CreateDirectory(workFolder);
                    list.Add(new FileBlobAdapter("/LOCALFILE/", direInfo.FullName + "\\"));

#if FileShareTest
                    list.Add(new FileBlobAdapter("/FileShare/", "\\", "\\\\cloudstoragelight.file.core.windows.net\\files", "cloudstoragelight", AppUtil.GetAppConfigValue("AzureFileSharePassword")));
#endif
                    _Container = new CompositeBlobContainer("unittest",
                        AppUtil.GetAppConfigValue("Composit.ConnectionString"), list);
                }
                return _Container; 
            }
        }

        [TestMethod]
        public void コンストラクタ()
        {
            Assert.IsNotNull(Container);
        }

        [TestMethod]
        public void SPSからAzureに移動()
        {
            var from = new BlobFile(Container, "/SPS/test.txt");
            var to = new BlobFile(Container, "/a.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(from, st).Wait();
            }

            if (Container.ExistsAsync(to.Path).Result)
            {
                Container.DeleteAsync(to).Wait();
            }

            Assert.IsFalse(Container.ExistsAsync(to.Path).Result);

            Container.CopyAsync(from, to.Path).Wait();

            Assert.IsTrue(Container.ExistsAsync(to.Path).Result);

            using (var st = new MemoryStream())
            {
                Container.DownloadAsync(to, st).Wait();
                Assert.AreEqual(32, st.ToArray()[0]);
            }
        }

        [TestMethod]
        public void FileからAzureに移動()
        {
            var from = new BlobFile(Container, "/LOCALFILE/test.txt");
            var to = new BlobFile(Container, "/b.txt");
            using (var st = new MemoryStream(new byte[] { 33 }))
            {
                Container.UploadAsync(from, st).Wait();
            }

            if (Container.ExistsAsync(to.Path).Result)
            {
                Container.DeleteAsync(to).Wait();
            }

            Assert.IsFalse(Container.ExistsAsync(to.Path).Result);

            Container.CopyAsync(from, to.Path).Wait();

            Assert.IsTrue(Container.ExistsAsync(to.Path).Result);

            using (var st = new MemoryStream())
            {
                Container.DownloadAsync(to, st).Wait();
                Assert.AreEqual(33, st.ToArray()[0]);
            }
        }

        [TestMethod]
        public void SPSからFileに移動()
        {
            var from = new BlobFile(Container, "/SPS/test.txt");
            var to = new BlobFile(Container, "/LOCALFILE/b.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(from, st).Wait();
            }

            if (Container.ExistsAsync(to.Path).Result)
            {
                Container.DeleteAsync(to).Wait();
            }

            Assert.IsFalse(Container.ExistsAsync(to.Path).Result);

            Container.CopyAsync(from, to.Path).Wait();

            Assert.IsTrue(Container.ExistsAsync(to.Path).Result);

            using (var st = new MemoryStream())
            {
                Container.DownloadAsync(to, st).Wait();
                Assert.AreEqual(32, st.ToArray()[0]);
            }
        }

        [TestMethod]
        public void まとめて検索()
        {
            var sps1 = new BlobFile(Container, "/SPS/test.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(sps1, st).Wait();
            }
            var file1 = new BlobFile(Container, "/LOCALFILE/test.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(file1, st).Wait();
            }
            var azure1 = new BlobFile(Container, "/AZURE/test.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(azure1, st).Wait();
            }

            var files = Container.GetFiles("/", 10000, true).Result;

            Assert.IsTrue(files.Any(x => x.Path == sps1.Path));
            Assert.IsTrue(files.Any(x => x.Path == file1.Path));
            Assert.IsTrue(files.Any(x => x.Path == azure1.Path));
        }

        [TestMethod]
        public void SharePointを検索()
        {
            var sps1 = new BlobFile(Container, "/SPS/test.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(sps1, st).Wait();
            }
            var files = Container.GetFiles("/SPS/", 10000, false).Result;

            Assert.IsTrue(files.Any(x => x.Path == sps1.Path));
        }

        [TestMethod]
        public void LocalFileを検索()
        {
            var file1 = new BlobFile(Container, "/LOCALFILE/test.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(file1, st).Wait();
            }
            var files = Container.GetFiles("/LOCALFILE/", 10000, false).Result;

            Assert.IsTrue(files.Any(x => x.Path == file1.Path));
        }

#if FileShare
        [TestMethod]
        public void FileShareを検索()
        {
            var file1 = new BlobFile(Container, "/FileShare/test.txt");
            using (var st = new MemoryStream(new byte[] { 32 }))
            {
                Container.UploadAsync(file1, st).Wait();
            }
            var files = Container.GetFiles("/FileShare/", 10000, false).Result;

            Assert.IsTrue(files.Any(x => x.Path == file1.Path));
        }
#endif
    }
}
